/*
 * CardReader class represents a device capable of ROM loading
 * CardReader subscribes to the Device interface
 * */

package system.device;

import os.File;
import cpu.components.DeviceUnit;
import cpu.datastores.Register16;
import cpu.interfaces.*;

public class CardReader implements Device {
	private DeviceUnit controller;
	
	public CardReader( ) {

	}
	
	public void enroll( int id, cpu.components.DeviceUnit controller ) {
		this.controller = controller;
		controller.enroll( id, this );
	}
	
	public void get( ) {
		// controller.DBR <- Device(controller.DID)
	}
	
	public void put( ) {
		// Device(controller.DID) <- controller.DBR;
		
		// CardReader read-only therefore cannot put to the device.
	}
	
	public void status( ) {
		// controller.DSR <- Device(controller.DID)
		// Note that this is a status query
	}
	
	public void boot( cpu.components.CPU cpu ) {
		// cpu reference passed so that card reader has wide range of access to 
		// all registers associated with initial state by reading the loader file, ie ControlUnit, MemoryController or others
	    
		// Reads the loader file.
		// loader file should have all instructions necessary to initialize system
		// ie, loading the trap functions and intializing the address space.
		// this includes loading program 1 and program 2 into memory		
		// loader file will use absolute addressing		
 
		File file=new File( "boot" );
		file.read( );
		cpu.memoryunit.caching=false;

		for( int j = 0; j < file.buffer.length; j++ )
		{
			cpu.deviceunit.DID.fromJavaInt( system.device.Identifiers.DEVICE_SWLATENCYSELECT.ordinal( ) );
			cpu.deviceunit.status( );
			if( cpu.deviceunit.DSR.toJavaInt( ) != 0 ) {
				cpu.deviceunit.get( );
				cpu.LATENCY.fromJavaInt( cpu.deviceunit.DBR.toJavaInt( ) );
			}
			
			char[] line = file.buffer[j].toCharArray( );
			
			Register16 addressword = new Register16( );
			Register16 dataword = new Register16( );
		
			for( int i = 0; i < 16; i++ ) {
				if( line[i] == '0' )
					addressword.bit(i).value = false;
				else
					addressword.bit(i).value = true;
			}
			for( int i = 16; i < 32; i++ ) {
				if( line[i] == '0' )
					dataword.bit( i-16 ).value = false;
				else
					dataword.bit( i-16 ).value = true;
			}
			cpu.memoryunit.MAR.fromWord( addressword );
			cpu.memoryunit.MBR.fromWord( dataword );
			cpu.memoryunit.put( );
			cpu.controlunit.updateMemoryAddressIndicator();
			cpu.controlunit.updateMemoryBufferIndicator();

			cpu.idle( );
		}	
		cpu.memoryunit.caching=true;
	}
	
}
